package edu.unf.cen6940.service;

import edu.unf.cen6940.dao.CategoryDAO;
import edu.unf.cen6940.dao.GeneratedproductDAO;
import edu.unf.cen6940.dao.StudentDAO;
import edu.unf.cen6940.dao.ThesisDAO;
import edu.unf.cen6940.dao.ThesiscommitteeDAO;
import edu.unf.cen6940.dao.ThesisstatusDAO;
import edu.unf.cen6940.dao.ThesistoolDAO;

import edu.unf.cen6940.domain.Category;
import edu.unf.cen6940.domain.Generatedproduct;
import edu.unf.cen6940.domain.Student;
import edu.unf.cen6940.domain.Thesis;
import edu.unf.cen6940.domain.Thesiscommittee;
import edu.unf.cen6940.domain.Thesisstatus;
import edu.unf.cen6940.domain.Thesistool;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for Thesis entities
 * 
 */

@Service("ThesisService")
@Transactional
public class ThesisServiceImpl implements ThesisService {

	/**
	 * DAO injected by Spring that manages Category entities
	 * 
	 */
	@Autowired
	private CategoryDAO categoryDAO;

	/**
	 * DAO injected by Spring that manages Generatedproduct entities
	 * 
	 */
	@Autowired
	private GeneratedproductDAO generatedproductDAO;

	/**
	 * DAO injected by Spring that manages Student entities
	 * 
	 */
	@Autowired
	private StudentDAO studentDAO;

	/**
	 * DAO injected by Spring that manages Thesis entities
	 * 
	 */
	@Autowired
	private ThesisDAO thesisDAO;

	/**
	 * DAO injected by Spring that manages Thesiscommittee entities
	 * 
	 */
	@Autowired
	private ThesiscommitteeDAO thesiscommitteeDAO;

	/**
	 * DAO injected by Spring that manages Thesisstatus entities
	 * 
	 */
	@Autowired
	private ThesisstatusDAO thesisstatusDAO;

	/**
	 * DAO injected by Spring that manages Thesistool entities
	 * 
	 */
	@Autowired
	private ThesistoolDAO thesistoolDAO;

	/**
	 * Instantiates a new ThesisServiceImpl.
	 *
	 */
	public ThesisServiceImpl() {
	}

	/**
	 * Return a count of all Thesis entity
	 * 
	 */
	@Transactional
	public Integer countThesiss() {
		return ((Long) thesisDAO.createQuerySingleResult("select count(o) from Thesis o").getSingleResult()).intValue();
	}

	/**
	 * Delete an existing Thesiscommittee entity
	 * 
	 */
	@Transactional
	public Thesis deleteThesisThesiscommittees(Integer thesis_thesisId, Integer related_thesiscommittees_thesisCommitteeId) {
		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesis_thesisId, -1, -1);
		Thesiscommittee related_thesiscommittees = thesiscommitteeDAO.findThesiscommitteeByPrimaryKey(related_thesiscommittees_thesisCommitteeId, -1, -1);

		thesis.getThesiscommittees().remove(related_thesiscommittees);
		related_thesiscommittees.getThesises().remove(thesis);
		thesis = thesisDAO.store(thesis);
		thesisDAO.flush();

		related_thesiscommittees = thesiscommitteeDAO.store(related_thesiscommittees);
		thesiscommitteeDAO.flush();

		thesiscommitteeDAO.remove(related_thesiscommittees);
		thesiscommitteeDAO.flush();

		return thesis;
	}

	/**
	 * Save an existing Generatedproduct entity
	 * 
	 */
	@Transactional
	public Thesis saveThesisGeneratedproducts(Integer thesisId, Generatedproduct related_generatedproducts) {
		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesisId, -1, -1);
		Generatedproduct existinggeneratedproducts = generatedproductDAO.findGeneratedproductByPrimaryKey(related_generatedproducts.getGeneratedProductId());

		// copy into the existing record to preserve existing relationships
		if (existinggeneratedproducts != null) {
			existinggeneratedproducts.setGeneratedProductId(related_generatedproducts.getGeneratedProductId());
			existinggeneratedproducts.setProductName(related_generatedproducts.getProductName());
			existinggeneratedproducts.setProductDescription(related_generatedproducts.getProductDescription());
			related_generatedproducts = existinggeneratedproducts;
		} else {
			related_generatedproducts = generatedproductDAO.store(related_generatedproducts);
			generatedproductDAO.flush();
		}

		related_generatedproducts.getThesises().add(thesis);
		thesis.getGeneratedproducts().add(related_generatedproducts);
		related_generatedproducts = generatedproductDAO.store(related_generatedproducts);
		generatedproductDAO.flush();

		thesis = thesisDAO.store(thesis);
		thesisDAO.flush();

		return thesis;
	}

	/**
	 * Delete an existing Category entity
	 * 
	 */
	@Transactional
	public Thesis deleteThesisCategories(Integer thesis_thesisId, Integer related_categories_categoryId) {
		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesis_thesisId, -1, -1);
		Category related_categories = categoryDAO.findCategoryByPrimaryKey(related_categories_categoryId, -1, -1);

		thesis.getCategories().remove(related_categories);
		related_categories.getThesises().remove(thesis);
		thesis = thesisDAO.store(thesis);
		thesisDAO.flush();

		related_categories = categoryDAO.store(related_categories);
		categoryDAO.flush();

/*		categoryDAO.remove(related_categories);
		categoryDAO.flush();*/

		return thesis;
	}

	/**
	 * Save an existing Thesiscommittee entity
	 * 
	 */
	@Transactional
	public Thesis saveThesisThesiscommittees(Integer thesisId, Thesiscommittee related_thesiscommittees) {
		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesisId, -1, -1);
		Thesiscommittee existingthesiscommittees = thesiscommitteeDAO.findThesiscommitteeByPrimaryKey(related_thesiscommittees.getThesisCommitteeId());

		// copy into the existing record to preserve existing relationships
		if (existingthesiscommittees != null) {
			existingthesiscommittees.setThesisCommitteeId(related_thesiscommittees.getThesisCommitteeId());
			related_thesiscommittees = existingthesiscommittees;
		} else {
			related_thesiscommittees = thesiscommitteeDAO.store(related_thesiscommittees);
			thesiscommitteeDAO.flush();
		}

		thesis.getThesiscommittees().add(related_thesiscommittees);
		related_thesiscommittees.getThesises().add(thesis);
		thesis = thesisDAO.store(thesis);
		thesisDAO.flush();

		related_thesiscommittees = thesiscommitteeDAO.store(related_thesiscommittees);
		thesiscommitteeDAO.flush();

		return thesis;
	}

	/**
	 * Return all Thesis entity
	 * 
	 */
	@Transactional
	public List<Thesis> findAllThesiss(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Thesis>(thesisDAO.findAllThesiss(startResult, maxRows));
	}

	/**
	 * Save an existing Thesisstatus entity
	 * 
	 */
	@Transactional
	public Thesis saveThesisThesisstatuses(Integer thesisId, Thesisstatus related_thesisstatuses) {
		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesisId, -1, -1);
		Thesisstatus existingthesisstatuses = thesisstatusDAO.findThesisstatusByPrimaryKey(related_thesisstatuses.getThesisStatusId());

		// copy into the existing record to preserve existing relationships
		if (existingthesisstatuses != null) {
			existingthesisstatuses.setThesisStatusId(related_thesisstatuses.getThesisStatusId());
			existingthesisstatuses.setProposed(related_thesisstatuses.getProposed());
			existingthesisstatuses.setProposalDate(related_thesisstatuses.getProposalDate());
			existingthesisstatuses.setDefended(related_thesisstatuses.getDefended());
			existingthesisstatuses.setDefenseDate(related_thesisstatuses.getDefenseDate());
			existingthesisstatuses.setProposalPass(related_thesisstatuses.getProposalPass());
			existingthesisstatuses.setDefensePass(related_thesisstatuses.getDefensePass());
			existingthesisstatuses.setComments(related_thesisstatuses.getComments());
			related_thesisstatuses = existingthesisstatuses;
		} else {
			related_thesisstatuses = thesisstatusDAO.store(related_thesisstatuses);
			thesisstatusDAO.flush();
		}

		related_thesisstatuses.getThesises().add(thesis);
		thesis.getThesisstatuses().add(related_thesisstatuses);
		related_thesisstatuses = thesisstatusDAO.store(related_thesisstatuses);
		thesisstatusDAO.flush();

		thesis = thesisDAO.store(thesis);
		thesisDAO.flush();

		return thesis;
	}

	/**
	 * Delete an existing Thesistool entity
	 * 
	 */
	@Transactional
	public Thesis deleteThesisThesistools(Integer thesis_thesisId, Integer related_thesistools_thesisToolId) {
		Thesistool related_thesistools = thesistoolDAO.findThesistoolByPrimaryKey(related_thesistools_thesisToolId, -1, -1);

		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesis_thesisId, -1, -1);

		related_thesistools.getThesises().remove(thesis);
		thesis.getThesistools().remove(related_thesistools);

		thesistoolDAO.remove(related_thesistools);
		thesistoolDAO.flush();

		return thesis;
	}

	/**
	 * Delete an existing Student entity
	 * 
	 */
	@Transactional
	public Thesis deleteThesisStudent(Integer thesis_thesisId, Integer related_student_studentId) {
		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesis_thesisId, -1, -1);
		Student related_student = studentDAO.findStudentByPrimaryKey(related_student_studentId, -1, -1);

		thesis.setStudent(null);
		related_student.getThesises().remove(thesis);
		thesis = thesisDAO.store(thesis);
		thesisDAO.flush();

		related_student = studentDAO.store(related_student);
		studentDAO.flush();

		studentDAO.remove(related_student);
		studentDAO.flush();

		return thesis;
	}

	/**
	 * Delete an existing Generatedproduct entity
	 * 
	 */
	@Transactional
	public Thesis deleteThesisGeneratedproducts(Integer thesis_thesisId, Integer related_generatedproducts_generatedProductId) {
		Generatedproduct related_generatedproducts = generatedproductDAO.findGeneratedproductByPrimaryKey(related_generatedproducts_generatedProductId, -1, -1);

		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesis_thesisId, -1, -1);

		related_generatedproducts.getThesises().remove(thesis);
		thesis.getGeneratedproducts().remove(related_generatedproducts);

		generatedproductDAO.remove(related_generatedproducts);
		generatedproductDAO.flush();

		return thesis;
	}

	/**
	 * Save an existing Category entity
	 * 
	 */
	@Transactional
	public Thesis saveThesisCategories(Integer thesisId, Category related_categories) {
		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesisId, -1, -1);
		Category existingcategories = categoryDAO.findCategoryByPrimaryKey(related_categories.getCategoryId());

		// copy into the existing record to preserve existing relationships
		if (existingcategories != null) {
			existingcategories.setCategoryId(related_categories.getCategoryId());
			existingcategories.setCategoryDescription(related_categories.getCategoryDescription());
			related_categories = existingcategories;
		} else {
			related_categories = categoryDAO.store(related_categories);
			categoryDAO.flush();
		}

		thesis.getCategories().add(related_categories);
		related_categories.getThesises().add(thesis);
		thesis = thesisDAO.store(thesis);
		thesisDAO.flush();

		related_categories = categoryDAO.store(related_categories);
		categoryDAO.flush();

		return thesis;
	}

	/**
	 * Save an existing Thesistool entity
	 * 
	 */
	@Transactional
	public Thesis saveThesisThesistools(Integer thesisId, Thesistool related_thesistools) {
		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesisId, -1, -1);
		Thesistool existingthesistools = thesistoolDAO.findThesistoolByPrimaryKey(related_thesistools.getThesisToolId());

		// copy into the existing record to preserve existing relationships
		if (existingthesistools != null) {
			existingthesistools.setThesisToolId(related_thesistools.getThesisToolId());
			existingthesistools.setToolDescription(related_thesistools.getToolDescription());
			related_thesistools = existingthesistools;
		} else {
			related_thesistools = thesistoolDAO.store(related_thesistools);
			thesistoolDAO.flush();
		}

		related_thesistools.getThesises().add(thesis);
		thesis.getThesistools().add(related_thesistools);
		related_thesistools = thesistoolDAO.store(related_thesistools);
		thesistoolDAO.flush();

		thesis = thesisDAO.store(thesis);
		thesisDAO.flush();

		return thesis;
	}

	/**
	 */
	@Transactional
	public Thesis findThesisByPrimaryKey(Integer thesisId) {
		return thesisDAO.findThesisByPrimaryKey(thesisId);
	}

	/**
	 * Load an existing Thesis entity
	 * 
	 */
	@Transactional
	public Set<Thesis> loadThesiss() {
		return thesisDAO.findAllThesiss();
	}

	/**
	 * Save an existing Thesis entity
	 * 
	 */
	@Transactional
	public void saveThesis(Thesis thesis) {
		Thesis existingThesis = thesisDAO.findThesisByPrimaryKey(thesis.getThesisId());

		if (existingThesis != null) {
			if (existingThesis != thesis) {
				existingThesis.setThesisId(thesis.getThesisId());
				existingThesis.setTitle(thesis.getTitle());
				existingThesis.setAbstract_(thesis.getAbstract_());
				existingThesis.setProposalAttempts(thesis.getProposalAttempts());
				existingThesis.setDefenseAttempts(thesis.getDefenseAttempts());
				existingThesis.setStartDate(thesis.getStartDate());
				existingThesis.setDoi(thesis.getDoi());
			}
			thesis = thesisDAO.store(existingThesis);
		} else {
			thesis = thesisDAO.store(thesis);
		}
		thesisDAO.flush();
	}

	/**
	 * Save an existing Student entity
	 * 
	 */
	@Transactional
	public Thesis saveThesisStudent(Integer thesisId, Student related_student) {
		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesisId, -1, -1);
		Student existingstudent = studentDAO.findStudentByPrimaryKey(related_student.getStudentId());

		// copy into the existing record to preserve existing relationships
		if (existingstudent != null) {
			existingstudent.setStudentId(related_student.getStudentId());
			existingstudent.setNnumber(related_student.getNnumber());
			existingstudent.setFirstName(related_student.getFirstName());
			existingstudent.setLastName(related_student.getLastName());
			existingstudent.setEmail(related_student.getEmail());
			existingstudent.setMajor(related_student.getMajor());
			existingstudent.setGraduated(related_student.getGraduated());
			existingstudent.setCurrentPosition(related_student.getCurrentPosition());
			existingstudent.setYearGraduated(related_student.getYearGraduated());
			related_student = existingstudent;
		}

		thesis.setStudent(related_student);
		related_student.getThesises().add(thesis);
		thesis = thesisDAO.store(thesis);
		thesisDAO.flush();

		related_student = studentDAO.store(related_student);
		studentDAO.flush();

		return thesis;
	}

	/**
	 * Delete an existing Thesisstatus entity
	 * 
	 */
	@Transactional
	public Thesis deleteThesisThesisstatuses(Integer thesis_thesisId, Integer related_thesisstatuses_thesisStatusId) {
		Thesisstatus related_thesisstatuses = thesisstatusDAO.findThesisstatusByPrimaryKey(related_thesisstatuses_thesisStatusId, -1, -1);

		Thesis thesis = thesisDAO.findThesisByPrimaryKey(thesis_thesisId, -1, -1);

		related_thesisstatuses.getThesises().remove(thesis);
		thesis.getThesisstatuses().remove(related_thesisstatuses);

		thesisstatusDAO.remove(related_thesisstatuses);
		thesisstatusDAO.flush();

		return thesis;
	}

	/**
	 * Delete an existing Thesis entity
	 * 
	 */
	@Transactional
	public void deleteThesis(Thesis thesis) {
		thesisDAO.remove(thesis);
		thesisDAO.flush();
	}
}
